package cn.simonfish.carrier.data;

import cn.simonfish.carrier.kit.NumberKit;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by simon on 2017/9/30.
 */
public class DataCrawling {

    private static Logger logger = LoggerFactory.getLogger(DataCrawling.class);

    private static ScheduledExecutorService scheduledExecutorService = Executors
            .newSingleThreadScheduledExecutor(new ThreadFactory(){
                private final AtomicLong threadIndex = new AtomicLong(0L);
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "coin_catch" + this.threadIndex.incrementAndGet());
                }
            });
    private static volatile boolean initialized = false;

    public static void initialize() {
        if(initialized == true){
            return;
        }
        //TODO 超时的时间，比整个网关少3秒
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                scanCrawlingFromDb();
            }
        },3,PropKit.getInt("crawling.period"), TimeUnit.SECONDS);
        initialized = true;
    }


    private static Sites GLOBAL_SITES = new Sites();

    public static Site getSite(String site){
        return GLOBAL_SITES.get(site);
    }
    /**
     * CREATE TABLE `QUOTE_DATA` (
     `WEBSITE` varchar(20) DEFAULT NULL,
     `COIN` varchar(20) DEFAULT NULL,
     `BIDPRICE` float DEFAULT NULL,
     `BIDVOLUME` float DEFAULT NULL,
     `ASKPRICE` float DEFAULT NULL,
     `ASKVOLUME` float DEFAULT NULL,
     `UPDATETIME` varchar(20) DEFAULT NULL,
     KEY `QUOTES_PK` (`WEBSITE`,`COIN`) USING BTREE
     * 扫描已经超时的请求。并发回超时响应
     */
    private static void scanCrawlingFromDb() {
        try {
            Sites sites = new Sites();
            List<Record> list = Db.use().find("select WEBSITE,COIN,BIDPRICE,BIDVOLUME,ASKPRICE,ASKVOLUME from QUOTE_DATA order by WEBSITE");
            String  lastSite = "";
            Site site = new Site();
            for (Record record: list        ) {
                String siteName= record.getStr("WEBSITE");
//                System.out.println(record);
                if(!siteName.equals(lastSite)){
                    sites.put(lastSite,site);
                    site = new Site();
                }
                CoinInfo coin = new CoinInfo();
                coin.setBidprice(NumberKit.toDouble( record.getDouble("BIDPRICE")));
                coin.setBidvolume(NumberKit.toDouble( record.getDouble("BIDVOLUME")));
                coin.setAskprice(NumberKit.toDouble( record.getDouble("ASKPRICE")));
                coin.setAskvolume(NumberKit.toDouble( record.getDouble("ASKVOLUME")));
                site.put(record.getStr("COIN"),coin);
                lastSite = siteName;
            }

            GLOBAL_SITES = sites;
            logger.info("reload data.size:{}",sites.size());
//            System.out.println(sites);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }
    /**
     * 扫描已经超时的请求。并发回超时响应
     */
    private static void scanCrawlingFromFile() {
        try {
//            String json = Jsoup.connect(PropKit.get("crawling.url")).execute().body();
            Sites sites = new Sites();
            byte[] data = Files.readAllBytes(new File("D:\\codespace\\me\\carrier\\src\\main\\resources\\data.json").toPath());
            String json = new String(data,"UTF-8");
            JSONObject jsonObject = JSON.parseObject(json);
            for (Map.Entry<String,Object> entry: jsonObject.entrySet()   ) {
                Site site = new Site();
                JSONObject siteJson = (JSONObject)entry.getValue();
                for (String key : siteJson.keySet()   ) {
                    CoinInfo coin = siteJson.getObject(key,CoinInfo.class);
                    site.put(key,coin);
                }
                sites.put(entry.getKey(),site);
            }
            GLOBAL_SITES = sites;
            System.out.println(sites);
        } catch (IOException e) {
            logger.error(e.getMessage(),e);
        }
    }

    public static void main(String[] args) {
        PropKit.use("conf.properties");
        scanCrawlingFromDb();
    }
}
